package com.acme.mock;

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

public class BankServer {
	ServerSocket providerSocket;
	Socket connection = null;
	ObjectOutputStream out;
	ObjectInputStream in;
	String message;
	BankService bankService;
	private Bank bank;
	boolean done;

	BankServer() {
		bankService = new BankService();
		done = false;
	}

	private void run() {
		try {
			// 1. creating a server socket
			providerSocket = new ServerSocket(2004, 10);
			// 2. Wait for connection
			System.out.println("Waiting for connection");
			connection = providerSocket.accept();
			System.out.println("Connection received from "
					+ connection.getInetAddress().getHostName());
			// 3. get Input and Output streams
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			sendMessage("Connection successful");
			message = (String) in.readObject();
			 System.out.println("client>" + message);
			// 4. The two parts communicate via the input and output streams
			do {
				try {
					Command command = (Command) in.readObject();
					System.out.println(command);
					String answer = parseQuery(command);
					System.out.println("Bank before save" + bank);
					saveToFile();
					sendMessage(answer);
				} catch (ClassNotFoundException classnot) {
					System.err.println("Data received in unknown format");
				} catch(SocketException | EOFException e) {
					done = true;
				}
			} while (!done);
		} catch (IOException | ClassNotFoundException ioException) {
			ioException.printStackTrace();
		} finally {
			// 4: Closing connection
			try {
				in.close();
				out.close();
				providerSocket.close();
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
	}

	void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println("server>" + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}

	private String parseQuery(Command command) {
		if(command.getWhatToDo().equals("add")) {
			return bankService.addClient(command.getAccountType(),
				command.getBalance(), command.getOverdraft(),
				command.getName(), command.getGender(), bank);
		} else {
			return bankService.deleteClient(command.getName(), bank);
		}
		
	}

	// TODO: [VY] Ups.. It seems to me that you don't understand multythreading clearly.
	// Please read this article before proceed: http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
	public void startServer() {
		while (true) {
			run();
		}
	}

	public void loadFromFile() throws IOException,
			ClassNotFoundException {
		FileInputStream fis = new FileInputStream("bank.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		bank = (Bank) ois.readObject();
		ois.close();
		fis.close();
		System.out.println(bank);
	}

	private void saveToFile() throws IOException {
		FileOutputStream fos = new FileOutputStream("bank.txt");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(bank);
		oos.close();
		fos.close();
	}
	
}
